﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Mvc;
using Microhard.Permission.Interface;
using Microhard.Permission.Models;
using Telerik.Web.Mvc;
using Microhard.ApproveWorkflow.Interfaces;
using System.Reflection;
using Microhard.Core;
using Microhard.Core.DBUtility;
using Microhard.Framework.MVCHelper;
using Microhard.Core.Algorithm;
using Microhard.ApproveWorkflow.Models;
using System.Web.Routing;
using Microhard.Permission.MVCFilter;


namespace Microhard.Permission.Interface
{

    /// <summary>
    /// 程琳
    /// </summary>
    [AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, Inherited = true, AllowMultiple = true)]
    public class AuthFuncFilterAttribute : ActionFilterAttribute
    {
        private IFuncAuthorization per = IoC.Resolve<IFuncAuthorization>();
        private IUser user = IoC.Resolve<IUser>();
        private IDataPermission id = IoC.Resolve<IDataPermission>();
        private IDataCollectionAuthorization ica = IoC.Resolve<IDataCollectionAuthorization>();
        private IWorkflow iwf = IoC.Resolve<IWorkflow>();

        /// <summary>
        /// 资源标示
        /// </summary>
        public string ResouceKeyName { set; get; }
        /// <summary>
        /// 行为标示
        /// </summary>
        public string OperationKeyName { set; get; }
        /// <summary>
        /// 接收数据权限结果的参数名称
        /// </summary>
        public string DataScopeactionParameterName { set; get; }
        /// <summary>
        /// 工作流参数名称
        /// </summary>
        public string WorkflowParameterName { set; get; }

        public bool JustValidatingIsLogOn { set; get; }

        public AuthFuncFilterAttribute()
        {
            this.DataScopeactionParameterName = "scope";
            this.WorkflowParameterName = "wfm";
        }

        private void RedirectToForbidden(ActionExecutingContext filterContext)
        {
            user.SignOut();
            filterContext.HttpContext.Session.Clear();
            if (filterContext.RequestContext.HttpContext.Request.IsAjaxRequest())
            {
                filterContext.Result = new JsonResult()
                {
                    Data = "您没有访问权限，请向系统管理员申请开放"
                };
            }
            else
            {
                var ad = new ViewResult();
                ad.ViewName = "AccessDenied";
                filterContext.Result = ad;
            }
        }

        private void RedirectToPreviousPage(ActionExecutingContext filterContext)
        {
            var ar = new RedirectResult("index");
            filterContext.Result = ar;
        }

        private void RedirectToDoNotNeedFlowPage(ActionExecutingContext filterContext)
        {
            if (filterContext.RequestContext.HttpContext.Request.IsAjaxRequest())
            {
                filterContext.Result = new JsonResult()
                {
                    Data = "此资源无需流程审批，请联系系统管理员"
                };
            }
            else
            {
                var ad = new ViewResult();
                ad.ViewName = "ResouceDoNotNeedFlowToExecute";
                filterContext.Result = ad;
            }
        }

        private void RedirectToNoAuthToAccessActivity(ActionExecutingContext filterContext)
        {
            if (filterContext.RequestContext.HttpContext.Request.IsAjaxRequest())
            {
                filterContext.Result = new JsonResult()
                {
                    Data = "您没有此业务节点的审批权限，请联系系统管理员"
                };
            }
            else
            {
                var ad = new ViewResult();
                ad.ViewName = "UserDoNotHasAuthToAccess";
                filterContext.Result = ad;
            }
        }


        private void RedirectToNeedFlowPage(ActionExecutingContext filterContext)
        {
            if (filterContext.RequestContext.HttpContext.Request.IsAjaxRequest())
            {
                filterContext.Result = new JsonResult()
                {
                    Data = "此资源不能直接操作，需要进行流程审批，请联系系统管理员！"
                };
            }
            else
            {
                var ad = new ViewResult();
                ad.ViewName = "ResouceNeedFlowToExecute";
                filterContext.Result = ad;
            }
        }

        public override void OnActionExecuted(ActionExecutedContext filterContext)
        {
            if (FilterHelper.IsSysAdminAction(filterContext.ActionDescriptor.ControllerDescriptor.ControllerName))
            {
                return;
            }
            var currentUser = filterContext.HttpContext.Session["userInfo"] as User;
            if (currentUser != null)
            {
                var actionName = filterContext.ActionDescriptor.ActionName.ToLower();
                IAfterActionDataFilter filter = ActionFilterFactory.GetActionExecutedFilter(actionName, iwf, id);
                if (filter != null)
                {
                    filter.FilterAction(filterContext, currentUser);
                }
            }
        }

        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            string actionName = filterContext.ActionDescriptor.ActionName.ToLower();
            string ctrName = filterContext.ActionDescriptor.ControllerDescriptor.ControllerName.ToLower();
            bool isSysAction = FilterHelper.IsSysAdminAction(filterContext.ActionDescriptor.ControllerDescriptor.ControllerName);

            if (!filterContext.HttpContext.User.Identity.IsAuthenticated)
            {
                this.RedirectToForbidden(filterContext);
                return;
            }
            else
            {
                var currentUser = filterContext.HttpContext.Session["userInfo"] as User;
                //如果用户信息为空，则跳转页面
                if (currentUser == null)
                {
                    this.RedirectToForbidden(filterContext);
                    return;
                }

                if (JustValidatingIsLogOn)
                    return;

                string userName = filterContext.HttpContext.User.Identity.Name;
                if (string.IsNullOrEmpty(userName))
                {
                    this.RedirectToForbidden(filterContext);
                    return;
                }
                else
                {
                    //组装验证基本信息
                    //如果此资源拥有流程，则添加，删除，修改自动跳转到流程action上
                    PermissionRequest pr = new PermissionRequest();
                    pr.RequestOperation = new Operation();
                    pr.RequestResouce = new Resouce();
                    if (string.IsNullOrEmpty(this.OperationKeyName))
                    {
                        pr.RequestOperation.KeyName = actionName;
                    }
                    else
                    {
                        pr.RequestOperation.KeyName = this.OperationKeyName.ToLower();
                    }
                    if (string.IsNullOrEmpty(this.ResouceKeyName))
                    {
                        pr.RequestResouce.KeyName = ctrName;
                    }
                    else
                    {
                        pr.RequestResouce.KeyName = this.ResouceKeyName.ToLower();
                    }
                    pr.UserName = currentUser.UserName;

                    List<string> hasPms = new List<string>();
                    List<Microhard.Permission.Models.Permission> currentPermissions = null;

                    //是否拥有功能权限
                    if (!per.IsApprove(pr, out hasPms, out currentPermissions))
                    {
                        this.RedirectToForbidden(filterContext);
                        return;
                    }
                    else
                    {
                        //验证通过，把用户对资源的操作赋值到Form Items中，为页面是否创建行为提供依据
                        filterContext.HttpContext.Items.Remove(SysConst.OPERATION_ITEM_KEYNAME);
                        filterContext.HttpContext.Items.Remove(SysConst.DATACOLLECTION_PERMISSIONID);
                        filterContext.HttpContext.Items.Add(SysConst.OPERATION_ITEM_KEYNAME, hasPms);
                        filterContext.HttpContext.Items.Add(SysConst.DATACOLLECTION_PERMISSIONID, currentPermissions.Select(p => p.PermissionID).ToList());

                        //传入拥有的数据权限,admin模块不进行验证,注:FluentValidation的验证发生在Model binding时期。此时的model已经
                        //被验证过
                        var dataScope = ica.GetDataScope(currentPermissions.Select(p => p.PermissionID).ToList(), currentUser.ID);
                        filterContext.ActionParameters[this.DataScopeactionParameterName] = dataScope;

                        //把scope信息添加到session中
                        var tmpUser = filterContext.HttpContext.Session["userInfo"] as User;
                        tmpUser.UserScope = dataScope;
                        filterContext.HttpContext.Session["userInfo"] = tmpUser;

                        if (!isSysAction)
                        {
                            bool IsWorkflowAction = false;
                            //数据权限验证
                            IActionDataFilter acFilter = ActionFilterFactory.GetActionFilter(actionName, out IsWorkflowAction);
                            if (acFilter != null)
                            {
                                //无数据权限访问，则跳转到禁止页面
                                if (!acFilter.FilterAction(filterContext, currentUser, currentPermissions, dataScope))
                                {
                                    this.RedirectToForbidden(filterContext);
                                    return;
                                }
                                else //拥有数据权限，才能验证是否有业务需要发起流程
                                {
                                    //加载流程上下文信息

                                    ApproveFlowChat flowChart = null;
                                    //如果是审批，归档，则表示业务已经有流程，直接通过业务ID获取流程
                                    string[] extflow = new string[] { "approve", "saveapprove", "complete", "savecomplete" };
                                    if (extflow.Contains(actionName))
                                    {
                                        flowChart = iwf.GetFlowChart(acFilter.PKID);
                                    }
                                    else
                                    {
                                        flowChart = iwf.GetFlowChart(dataScope.ResourceID, dataScope.OperationID);
                                    }
                                    if (flowChart != null)
                                    {
                                        var isApproveCtr = ctrName != "approveflow" ? false : true;
                                        iwf.scope = dataScope;
                                        //传递流程相关信息到action
                                        string realResource;
                                        var wfm = iwf.GetWorkFlowModel(acFilter.PKID, dataScope.ResourceID, out realResource);
                                        //用户没有权限对此节点业务进行操作（发起申请，审批,归档）
                                        if (!wfm.UserHasAuthToAccessActivity)
                                        {
                                            this.RedirectToNoAuthToAccessActivity(filterContext);
                                        }
                                        else
                                        {
                                            wfm.BusSheetApproveControllerName = isApproveCtr ? realResource : ctrName;
                                            wfm.BusSheetApproveViewName = wfm.HasActivities.SingleOrDefault(a => a.IsCurrent).ViewName;
                                            filterContext.ActionParameters[this.WorkflowParameterName] = wfm;
                                        }
                                    }
                                    else
                                    {
                                        if (IsWorkflowAction)
                                        {
                                            this.RedirectToDoNotNeedFlowPage(filterContext);
                                        }
                                    }
                                }
                            }


                        }

                    }
                }
            }


        }
    }
}
